#include "MyWifi.h"
#include <Arduino.h>
#include <WiFi.h>
#include <WebServer.h>   //网络失败配网
#include <DNSServer.h>   //网络失败配网
#include <Preferences.h> //持久化存储
#include <set>
// 自定义模块
#include "OledModule/Oled.h"
#include "MqttModule/MyMqtt.h"

WiFiClient espClient;

Preferences preferences;

WebServer server(80); // 创建一个Web服务器对象，端口为80
DNSServer dnsServer;  // DNS服务器对象

// 设置屏幕间隔时间
const unsigned long interval = 6000;
unsigned long previousMillis = 0; // 上次更新时间

IPAddress wifiIp; // 存储设备ip地址
String macAddress;

String ssidOption = ""; // 定义全局ssid选项
std::set<String> uniqueSSIDs; // 用于存储唯一 SSID

// 设置DNS服务器
IPAddress primaryDNS(8, 8, 8, 8);   // Google DNS
IPAddress secondaryDNS(223, 5, 5, 5); // 阿里：备用DNS服务器

bool setupWifi(const char *ssid, const char *password)
{
  delay(10);
  // 仅设置DNS服务器，其他参数使用DHCP
  if (!WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE, primaryDNS, secondaryDNS)) {
    Serial.println("STA Failed to configure DNS");
  }
  WiFi.begin(ssid, password);
  int retries = 0; // 重试次数
  while (WiFi.status() != WL_CONNECTED && retries < 20)
  {
    delay(500);
    Serial.print(".");
    retries++;
  }
  if (WiFi.status() == WL_CONNECTED)
  {
    wifiIp = WiFi.localIP();

    u8g2.clearBuffer();
    showTxt(0, 10, "Wifi Ok!");
    Serial.println("Wifi connect Ok!");
    u8g2.sendBuffer();
  }
  macAddress = WiFi.macAddress();
  Serial.println();
  return WiFi.status() == WL_CONNECTED;
}



void handlerSubmit()
{
  String new_ssid = server.arg("ssid");
  String new_password = server.arg("password");

  String new_deviceName = server.arg("deviceName");

  String new_server = server.arg("server");
  String new_port = server.arg("port");
  String new_user = server.arg("user");
  String new_pwd = server.arg("pwd");

  // 存储新配置并重新启动设备
  preferences.putString("ssid", new_ssid);
  preferences.putString("password", new_password);

  preferences.putString("deviceName", new_deviceName);
  

  preferences.putString("mqtt_server", new_server);
  preferences.putString("mqtt_port", new_port);
  preferences.putString("mqtt_user", new_user);
  preferences.putString("mqtt_password", new_pwd);
  
  // 发送带有美化的HTML页面的响应
  String html = R"(
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
        <title>Configuration Saved</title>
        <style>
            body {
                font-family: Arial, sans-serif;
                background-color: #f0f0f0;
                color: #333;
                text-align: center;
                padding: 50px;
            }
            .container {
                background-color: #fff;
                padding: 20px;
                border-radius: 8px;
                box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
                display: inline-block;
            }
            h1 {
                color: #4CAF50;
                margin-bottom: 20px;
            }
            p {
                font-size: 18px;
                margin-bottom: 20px;
            }
            .spinner {
                border: 4px solid #f3f3f3;
                border-radius: 50%;
                border-top: 4px solid #4CAF50;
                width: 40px;
                height: 40px;
                animation: spin 2s linear infinite;
                margin: 0 auto 20px;
            }
            @keyframes spin {
                0% { transform: rotate(0deg); }
                100% { transform: rotate(360deg); }
            }
        </style>
    </head>
    <body>
        <div class="container">
            <h1>Configuration Saved</h1>
            <div class="spinner"></div>
            <p>Configuration saved. Restarting...</p>
        </div>
    </body>
    </html>
  )";

  server.send(200, "text/html", html);

  delay(3000);// 延迟3秒以显示页面
  ESP.restart();
}

void handerIndex()
{
  

  String html=R"(<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>WiFi Configuration</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f4f4f4;
        }

        .container {
            background-color: #fff;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
            width: 100%;
            max-width: 400px;
            box-sizing: border-box;
        }

        h1 {
            font-size: 24px;
            margin-bottom: 20px;
            text-align: center;
        }

        input[type="text"],
        input[type="password"] {
            width: 100%;
            padding: 10px;
            margin: 10px 0;
            border: 1px solid #ccc;
            border-radius: 4px;
            box-sizing: border-box;
        }

        input[type="submit"] {
            width: 100%;
            background-color: #4CAF50;
            color: white;
            padding: 10px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 16px;
        }

        input[type="submit"]:hover {
            background-color: #45a049;
        }
        .option {
            display: inline-block;
            margin: 5px;
            padding: 10px;
            border: 1px solid #ccc;
            border-radius: 5px;
            cursor: pointer;
            background-color: #f9f9f9;
        }
        .option:active {
            background-color: #e0e0e0;
        }
    </style>
    <script>
        function fillInput(text) {
            document.getElementById('ssid').value = text;
        }
    </script>
</head>

<body>
    <div class="container">
        <form action="/config" method="post">
            <h1>WiFi Configuration</h1>
            <label for="ssid">SSID:</label>
            <input type="text" id="ssid" name="ssid" placeholder="Enter SSID" required><br>
            <div id="options">)";
  
  html+=ssidOption;

  html+=R"(</div>
            <label for="password">Password:</label>
            <input type="password" id="password" name="password" placeholder="Enter Password" required><br>
            <h1>Device Configuration</h1>
            <label for="deviceName">Device Name:</label>
            <input type="text" id="deviceName" name="deviceName" value="" placeholder="Enter deviceName" required><br>
            <h1>MQTT Configuration</h1>
            <label for="server">Server:</label>
            <input type="text" id="server" name="server" value="" placeholder="Enter Server Like:192.168.10.2" required><br>
            <label for="port">Port:</label>
            <input type="text" id="port" name="port" value="1883" placeholder="Enter Port Like:1883" required><br>
            <label for="user">User:</label>
            <input type="text" id="user" name="user" value="" placeholder="Enter User Like:esp32" required><br>
            <label for="pwd">Password:</label>
            <input type="text" id="pwd" name="pwd" value="" placeholder="Enter Password" required><br>
            <input type="submit" value="Save">
        </form>
    </div>
</body>

</html>)";

  server.send(200, "text/html", html);
}

// 当连接失败时，启动热点模式，并运行一个简单的 Web 服务器用于配网
void setupAP()
{
  WiFi.mode(WIFI_STA); // 设置 WiFi 模式为 STA
  WiFi.disconnect(); // 断开所有网络连接

  Serial.println("Scanning for WiFi networks...");
  ssidOption="";

  int n = WiFi.scanNetworks();
  if (n == -2) {
      Serial.println("Scan timed out.");
  } else if (n == -1) {
      Serial.println("Scan failed.");
  } else {
      Serial.print(n);
      Serial.println(" networks found");
      for (int i = 0; i < n; i++) {
          String ssid = WiFi.SSID(i);
          uniqueSSIDs.insert(ssid); // 插入到 set 中，自动去重
      }
      for (const auto& ssid : uniqueSSIDs) {
          ssidOption += "<div class='option' onclick=\"fillInput('" + ssid + "')\">" + ssid + "</div>";
      }
  }

  Serial.println(ssidOption);

  u8g2.clearBuffer();
  showTxt(0, 5, "AP Mode:");
  showTxt(0, 15, "ESP32-Config");
  

  WiFi.softAP("ESP32-Config", NULL); // 创建热点
  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(myIP);
  showTxt(0, 30, myIP.toString());
  u8g2.sendBuffer();

  dnsServer.start(53, "*", myIP); // 启动DNS服务器

  server.on("/", HTTP_GET, handerIndex);

  server.on("/config", HTTP_POST, handlerSubmit);

  server.begin();
}

void reflushShowWifiInfo()
{                         // 刷新显示wifi信息
  int rssi = WiFi.RSSI(); // 存储RSSI值
  if (rssi >= -30)
  {
    showWifiLogo("full_wifi");
  }
  else if (rssi < -30 && rssi >= -60)
  {
    showWifiLogo("middle_wifi");
  }
  else if (rssi < -60)
  {
    showWifiLogo("low_wifi");
  }
  // 显示RSSI
  u8g2.setCursor(24, 16);
  u8g2.setFont(u8g2_font_5x7_tr);
  u8g2.print(rssi);
  u8g2.print(" dBm");
  // 显示ip地址
  u8g2.setCursor(0, 30);
  u8g2.setFont(u8g2_font_5x7_tr);
  u8g2.print(wifiIp);
  u8g2.sendBuffer();
}

void reloadRssi()
{
  unsigned long currentMillis = millis(); // 获取当前时间

  // 检查是否到了更新时间
  if (currentMillis - previousMillis >= interval)
  {
    previousMillis = currentMillis; // 更新上次更新时间
    // 检查WiFi连接状态
    if (WiFi.status() == WL_CONNECTED && showMqStatus == false)
    {
      reflushShowWifiInfo(); // 调用刷新函数
    }
    else
    {
      // Serial.println("WiFi not connected. Skipping update.");
      showLiveTxt(0, 10, "WIFI Error!");
    }
  }
}